package com.version1_3.dao.implement;

import com.SQLGroup.SQLAccess;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.util.property.Properties;
import com.version1_3.dao.ActivityDao;
import com.version1_3.dao.UserDao1_3;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.Scope;
import org.springframework.dao.EmptyResultDataAccessException;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;

import java.math.BigDecimal;
import java.sql.Date;
import java.text.DecimalFormat;
import java.util.Calendar;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * Created by kuibu on 16/2/23.
 */
@Repository
public class ActivityDaoImpl implements ActivityDao {
    private static final Logger LOGGER = Logger.getLogger(ActivityDaoImpl.class);

    @Autowired
    private JdbcTemplate jdbcTemplate;

    @Autowired
    private UserDao1_3 userDao13;


    /**
     * 参与活动
     *
     * @param userId
     * @param activityId
     * @return
     */
    @Override
    public boolean joinActivity(int userId, int activityId) {
        String userJoinedActivityIds = userDao13.getUserJoinedActivityIds(userId);

        JSONArray actiJoinedJsonArray = JSON.parseArray(userJoinedActivityIds);

        // 如果参与的是跬步健身活动
        if (activityId == Properties.KbActivity_jianshenID) {
            if (userJoinedActivityIds.contains(String.valueOf(Properties.KbActivity_fuwocheng)) || userJoinedActivityIds.contains(String.valueOf(Properties.KbActivity_pingban)) || userJoinedActivityIds.contains(String.valueOf(Properties.KbActivity_yangwo))) {
                return true;
            } else {
                actiJoinedJsonArray.add(Properties.KbActivity_fuwocheng); // 增加俯卧撑项目
                actiJoinedJsonArray.add(Properties.KbActivity_pingban); // 增加平板支撑项目
                actiJoinedJsonArray.add(Properties.KbActivity_yangwo); // 增加仰卧起坐项目

                userDao13.updateUserJoinedActivityIds(userId, actiJoinedJsonArray);
                addActivityJoinNumber(activityId);
            }
        } else if (actiJoinedJsonArray.contains(activityId)) {
            return true;
        } else {
            actiJoinedJsonArray.add(activityId);
            userDao13.updateUserJoinedActivityIds(userId, actiJoinedJsonArray); // 更新用户活动参与信息
            addActivityJoinNumber(activityId); // 更新活动参与人数
        }

        return true;
    }


    /**
     * 更新活动参与人数
     */
    public boolean addActivityJoinNumber(int activityId) {
        int row = jdbcTemplate.update(SQLAccess.UpdateActivityJoinNumberVersion1_3, new Object[]{activityId});

        if (row != 1) {
            LOGGER.error("更新活动参与人数失败,activityId: " + activityId);
        }

        return (row == 1) ? true : false;
    }

    /**
     * 根据活动类型获取活动概况信息
     *
     * @param activityType
     * @return
     */
    @Override
    public List<Map<String, Object>> getActivityInfoByType(int activityType) {
        return jdbcTemplate.queryForList(SQLAccess.SelectActivityInfoByTypeVersion1_3, new Object[]{activityType});
    }

    /**
     * 根据活动ID获取活动概况信息
     *
     * @param activityId
     * @return
     */
    @Override
    public Map<String, Object> getActivityInfoById(int activityId) {
        return jdbcTemplate.queryForMap(SQLAccess.SelectActivityInfoByID_Version1_3, new Object[]{activityId});
    }

    /**
     * 获取用户活动总的打卡信息
     *
     * @param userId
     * @return
     */
    @Override
    public List<Map<String, Object>> getUserActivityInfo(int userId) {
        return jdbcTemplate.queryForList(SQLAccess.SelectUserActivityInfo, new Object[]{userId});
    }

    /**
     * 获取用户指定活动的总打卡信息
     *
     * @param userId
     * @param activityId
     * @return
     */
    @Override
    public Map<String, Object> getActivityInfo(int userId, int activityId) {
        return jdbcTemplate.queryForMap(SQLAccess.SelectUserSpecificActivityInfo, new Object[]{userId, activityId});
    }

    /**
     * 获取用户一周的打卡情况
     *
     * @param userId
     * @param activityId
     * @return
     */
    @Override
    public List<Map<String, Object>> getUserWeekLaunchInfo(int userId, int activityId) {
        return jdbcTemplate.queryForList(SQLAccess.SelectUserWeekLaunchCardInfo, new Object[]{userId, activityId});
    }


    /**
     * 获取用户活动打卡页面信息
     *
     * @param userId
     * @param activityId
     * @return
     */
    @Override
    public Map<String, Object> getUserLaunchPageInfo(int userId, int activityId) {
        try {
            Map<String, Object> resultMap = jdbcTemplate.queryForMap(SQLAccess.SelectUserLaunchPageInfo, new Object[]{userId, activityId});

            if (resultMap.get("userId") == null) {
                throw new EmptyResultDataAccessException(0);
            }
            return resultMap;
        } catch (EmptyResultDataAccessException exception) {
            LOGGER.info("用户该活动没有打过卡");

            // 用户该活动没有打过卡,返回默认值
            Map<String, Object> launchPageInfoMap = new HashMap<>();
            launchPageInfoMap.put("days", 0);
            launchPageInfoMap.put("coin", 0);
            launchPageInfoMap.put("calorie", 0);
            launchPageInfoMap.put("currData", new BigDecimal(0.00));
            launchPageInfoMap.put("currDataCount", new BigDecimal(0.00));
            launchPageInfoMap.put("maxCurrData", new BigDecimal(0.00));
            launchPageInfoMap.put("data1", 20);
            launchPageInfoMap.put("money", new DecimalFormat("#.00").format(0.00));
            Calendar calendar = Calendar.getInstance();
            calendar.add(Calendar.DATE, -2);
            launchPageInfoMap.put("date", calendar.getTime());
            return launchPageInfoMap;
        }

    }


    /**
     * 插入最新打卡数据
     *
     * @param userId
     * @param activityId
     * @param currData
     * @param data1
     * @param coin
     * @param money
     * @return
     */
    @Override
    public boolean addNewLaunchRecord(int userId, int activityId, String currData, String data1, int data3, int coin, double money) {
        try {
            jdbcTemplate.update(SQLAccess.AddUserLaunchCardInfo, new Object[]{userId, activityId, new java.util.Date(), currData, data1, data3, coin, money});
            return true;
        } catch (Exception exception) {
            LOGGER.error("插入新的打卡数据失败,userId: " + userId + " ,activityID: " + activityId + " ,currData: " + currData + " ,data1: " + data1 + " ,coin: " + coin + " ,money: " + money, exception);
            return false;
        }
    }

    /**
     * 更新最新打卡数据
     *
     * @param userId
     * @param activityId
     * @param currData
     * @param coin
     * @param money
     * @return
     */
    @Override
    public boolean freshLaunchRecord(int userId, int activityId, String currData, int data3, int coin, double money) {

        try {
            jdbcTemplate.update(SQLAccess.UpdateUserTodayLaunchCardData, new Object[]{currData, coin, money, data3, userId, activityId});
            return true;
        } catch (Exception exception) {
            LOGGER.error("刷新打卡数据失败,userId: " + userId + " ,activityID: " + activityId + " ,currData: " + currData + " ,coin: " + coin + " ,calorie: " + money);
            return false;
        }
    }

    /**
     * 把新的打卡数据加到当天打卡信息上
     *
     * @param userId
     * @param activityId
     * @param currData
     * @param data1
     * @param coin
     * @param money
     * @return
     */
    @Override
    public boolean addLaunchRecord(int userId, int activityId, String currData, String data1, int coin, double money) {
        try {
            jdbcTemplate.update(SQLAccess.AddNewDataToUserCurrentLaunchCardInfo, new Object[]{currData, data1, coin, money, userId, activityId});
            return true;
        } catch (Exception exception) {
            LOGGER.error("累加打卡数据失败,userId: " + userId + " ,activityID: " + activityId + " ,currData: " + currData + " ,data1: " + data1 + " ,coin: " + coin + " ,money: " + money);
            return false;
        }
    }


    /**
     * 给今日打卡的用户增加积分
     *
     * @param userId
     * @param activityId
     * @param coin
     * @return
     */
    @Override
    public boolean addUserActivityCoin(int userId, int activityId, int coin) {
        int row = jdbcTemplate.update(SQLAccess.AddUserTodayLaunchCardCoin, new Object[]{coin, userId, activityId});
        return (row == 1) ? true : false;
    }


    /**
     * 获取用户活动捐献钱数
     *
     * @param userId
     * @param activityId
     * @return
     */
    @Override
    public Map<String, Object> getShareLaunchCardInfo(int userId, int activityId) {
        Map<String, Object> shareLaunchCardInfo = new HashMap<>();
        Map<String, Object> userBodyInfoMap = userDao13.getUserBodyInfo(userId);

        if (activityId == 11) {
            // 公益跑
            try {
                Map<String, Object> resultMap = jdbcTemplate.queryForMap(SQLAccess.SelectUserActivityDonateMoneyGongyipao, new Object[]{userId, activityId});

                // 捐赠金额
                shareLaunchCardInfo.put("money", resultMap.get("money"));

                // 当日里程
                double mile = ((BigDecimal) userBodyInfoMap.get("height")).intValue() * 0.0075 * ((BigDecimal) resultMap.get("currData")).intValue();
                shareLaunchCardInfo.put("mile", String.format("%.3f", (mile / 1000)));

                // 总里程
                double mileCount = ((BigDecimal) userBodyInfoMap.get("height")).intValue() * 0.0075 * ((BigDecimal) resultMap.get("currDataCount")).intValue();
                shareLaunchCardInfo.put("mileCount", String.format("%.3f", (mileCount / 1000)));

                int timeCount = ((BigDecimal) resultMap.get("currData")).intValue();
                shareLaunchCardInfo.put("timeCount", timeCount);

                return shareLaunchCardInfo;
            } catch (EmptyResultDataAccessException exception) {
                LOGGER.error("用户该活动没有打过卡");
                return null;
            }
        }

        if (activityId == 13) {
            // 平板支撑
            try {
                Map<String, Object> resultMap = jdbcTemplate.queryForMap(SQLAccess.SelectUserActivityDonateMoneyPingban, new Object[]{userId, activityId});

                // 捐赠金额
                shareLaunchCardInfo.put("money", resultMap.get("money"));

                // 此次坚持时间
                shareLaunchCardInfo.put("seconds", ((BigDecimal) resultMap.get("currData")).intValue() / 100);

                // 总坚持时间
                shareLaunchCardInfo.put("secondsCount", ((BigDecimal) resultMap.get("currDataCount")).intValue() / 100);

                return shareLaunchCardInfo;
            } catch (EmptyResultDataAccessException exception) {
                LOGGER.error("用户该活动没有打过卡");
                return null;
            }
        }

        if (activityId == 14 || activityId == 15) {
            // 俯卧撑 | 仰卧起坐
            try {
                Map<String, Object> resultMap = jdbcTemplate.queryForMap(SQLAccess.SelectUserActivityDonateMoneyFuwochengAndYangwo, new Object[]{userId, activityId});

                // 捐赠金额
                shareLaunchCardInfo.put("money", resultMap.get("money"));

                // 此次做次数
                shareLaunchCardInfo.put("number", Integer.parseInt((String) resultMap.get("data1")) * ((BigDecimal) resultMap.get("currData")).intValue());

                // 总计个数
                shareLaunchCardInfo.put("numberCount", (int) ((double) resultMap.get("data1Count")) * 4);

                return shareLaunchCardInfo;
            } catch (EmptyResultDataAccessException exception) {
                LOGGER.error("用户该活动没有打过卡");
                return null;
            }
        }

        Map<String, Object> userInfoMap = userDao13.getUserInfo(userId);

        if (userInfoMap.get("school") != null) {
            shareLaunchCardInfo.put("school", userInfoMap.get("school"));
        } else {
            shareLaunchCardInfo.put("school", "未知学校");
        }

        return shareLaunchCardInfo;

    }

    @Override
    public Map<String, Object> getUserTodayActivityInfo(int userId, int activityId) {
        try {
            return jdbcTemplate.queryForMap(SQLAccess.SelectUserTodayActivityInfo, new Object[]{userId, activityId});
        } catch (Exception exception) {
            return null;
        }
    }

    /**
     * 获取用户今日活动打卡积分
     *
     * @param userId
     */
    @Override
    public int getUserLaunchCardCoin(int userId) {
        // 根据用户今天进行了几项打卡来计算,每打卡一项10分
        return (jdbcTemplate.queryForObject(SQLAccess.SelectUserLaunchCardActivityNumber, new Object[]{userId}, java.lang.Integer.class)) * 10;
    }

    /**
     * 获取用户活动打卡总积分
     *
     * @param userId
     */
    @Override
    public int getUserLaunchCardCoinCount(int userId) {
        // 根据用户今天进行了几项打卡来计算,每打卡一项10分
        return (jdbcTemplate.queryForObject(SQLAccess.SelectUserLaunchCardActivityNumberCount, new Object[]{userId}, java.lang.Integer.class)) * 10;
    }

    /**
     * 记录用户分享打卡活动
     *
     * @param userId
     * @param activityId
     * @return
     */
    @Override
    public boolean recordActivityShare(int userId, int activityId) {
        try {
            int rows = jdbcTemplate.update(SQLAccess.RecordUserShareActivity, new Object[]{userId, activityId});
            return (rows == 1) ? true : false;
        } catch (Exception exctpion) {
            return true;
        }
    }

    /**
     * 获取用户活动分享积分
     *
     * @param userId
     * @return
     */
    @Override
    public int getActivityShareCoin(int userId) {
        return (jdbcTemplate.queryForObject(SQLAccess.SelectUserActivityShareCoin, new Object[]{userId}, java.lang.Integer.class)) * 10;
    }

    /**
     * 获取用户活动分享总积分
     *
     * @param userId
     * @return
     */
    @Override
    public int getActivityShareCoinCount(int userId) {
        return (jdbcTemplate.queryForObject(SQLAccess.SelectUserActivityShareCoinCount, new Object[]{userId}, java.lang.Integer.class)) * 10;
    }


    /**
     * 获取用户活动坚持天数
     *
     * @param activityId
     * @return
     */
    @Override
    public int getInsistDays(int userId, int activityId) {

        if (activityId == Properties.KbActivity_jianshenID) {
            // 跬步公益健身
            String sql = "SELECT COUNT(*) FROM (SELECT userId,date,activityID FROM activity_launchrecord GROUP BY userId,date HAVING max(activityID)>=13) AS tt WHERE tt.userId=?";
            return jdbcTemplate.queryForObject(sql, new Object[]{userId}, java.lang.Integer.class);
        } else {
            // 跬步公益跑 | 跬步骑行
            String sql = "SELECT count(*) AS insistDays FROM (SELECT id FROM activity_launchrecord WHERE userId=? AND activityID=? GROUP BY date) AS tt";
            return jdbcTemplate.queryForObject(sql, new Object[]{userId, activityId}, java.lang.Integer.class);
        }
    }

    /**
     * 获取用户活动捐献总金额
     *
     * @param userId
     * @return
     */
    @Override
    public double getUserDonateMoneyCount(int userId) {

        String sql = ""; // SQL语句
        BigDecimal dayFirstLaunchMoney = new BigDecimal(0.00); // 每日第一次打卡获得金额
        double gongyipaoMoney = 0.00; // 公益跑捐赠金额
        double jianshenMoney = 0.00; // 跬步健身捐赠金额
        double pingban = 0.00; // 平板支撑捐献金额

        /**
         * 1. 所有活动当日第一次打卡签到获得金额
         */
        try {
            sql = "SELECT SUM(money) AS dayFirstLaunchMoney FROM activity_launchrecord WHERE userId=?";
            dayFirstLaunchMoney = jdbcTemplate.queryForObject(sql, new Object[]{userId}, java.math.BigDecimal.class);
        } catch (Exception excetpion) {
            LOGGER.info("用户没有活动打卡记录");
        }

        /**
         * 2. 公益跑跑步里程捐献金额
         */
        try {
            sql = "SELECT SUM(currData) FROM activity_launchrecord WHERE userId=? AND activityID=11"; // 公益跑跑步步数
            BigDecimal currDataCount = jdbcTemplate.queryForObject(sql, new Object[]{userId}, java.math.BigDecimal.class);

            Map<String, Object> userBodyInfoMap = userDao13.getUserBodyInfo(userId); // 获取身高体重信息,用来计算跑路里程和卡路里
            gongyipaoMoney = (((BigDecimal) userBodyInfoMap.get("height")).intValue() * 0.0075 * currDataCount.intValue()) / 100000;
        } catch (Exception exception) {
            LOGGER.info("用户公益跑没有打卡数据");
        }

        /**
         * 3. 仰卧起坐&俯卧撑捐献金额
         */
        try {
            sql = "SELECT SUM(data3) FROM activity_launchrecord WHERE userId=? AND activityID IN (14,15)"; // 公益跑跑步步数
            BigDecimal currDataCount = jdbcTemplate.queryForObject(sql, new Object[]{userId}, java.math.BigDecimal.class);

            jianshenMoney = currDataCount.intValue() / 80 * 0.01;
        } catch (Exception exception) {
            LOGGER.info("用户公益健身仰卧起坐和俯卧撑没有打卡数据");
        }

        /**
         * 4. 平板支撑捐献金额
         */
        try {
            sql = "SELECT SUM(data3) FROM activity_launchrecord WHERE userId=? AND activityID=13"; // 公益跑跑步步数
            BigDecimal currDataCount = jdbcTemplate.queryForObject(sql, new Object[]{userId}, java.math.BigDecimal.class);

            pingban = currDataCount.intValue() / 90 * 0.01;
        } catch (Exception exception) {
            LOGGER.info("用户公益健身仰卧起坐和俯卧撑没有打卡数据");
        }

        if (dayFirstLaunchMoney == null) {
            dayFirstLaunchMoney = new BigDecimal(0.00);
        }
        return dayFirstLaunchMoney.doubleValue() + gongyipaoMoney + jianshenMoney + pingban; // 总的捐献金额
    }
}
